﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ODM_Code.Forms
{
    public partial class ScenarioMetaForm : Form
    {
        private rUtils ru;
        private string inputPath = "C:\\magfire\\" + ConfigSettings.ReadSetting("analysisArea") + "\\input";
        private StreamWriter sw = null;
        private string reportTextName = "";
        StreamReader sr = null;

        public ScenarioMetaForm()
        {
            InitializeComponent();

            ru = new rUtils();
        }

        public void ScenarioMetaForm_Load(object sender, EventArgs e)
        {
            string[] files = System.IO.Directory.GetDirectories(inputPath);
            foreach (string s in files)
            {
                string[] spl = s.Split('\\');
                int i = spl.Length;

                string addThis = spl[i - 1];
                if (addThis.StartsWith("S"))
                {
                    this.alternativeSelectBox.Items.Add(spl[i - 1]);
                }
            }

            this.alternativeSelectBox.SelectedText = ConfigSettings.ReadSetting("currentAlternative");
        }

        private void butLoadData_Click(object sender, EventArgs e)
        {
            string resultsPath = inputPath + "\\" + alternativeSelectBox.Text + "\\results";

            if (clearOldReportsCheckBox.Checked)
            {
                this.clearOldReports(resultsPath);
            }


            ru.CheckMultifireBounds(resultsPath);
            ru.CheckPeriodBounds(resultsPath);

            bool writeNewDoc = createNewFileCheckbox.Checked;

            if (writeNewDoc == true)
            {

                reportTextName = resultsPath + "\\Report_" + DateTime.Now.ToString("yyMMdd_hhmmss") + ".txt";
                sw = new StreamWriter(reportTextName, false, ASCIIEncoding.ASCII);

                sw.WriteLine("OptFuels Report");
                sw.WriteLine(DateTime.Now.ToString());
                sw.WriteLine();
            }

            try
            {
                this.updateMainParams(writeNewDoc);
                this.updateFireParams(writeNewDoc);
                this.updateAreaConstraints(writeNewDoc);
                this.updateCostConstraints(writeNewDoc);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "Updating Meta Report");
                MessageBox.Show("Error reading results. Data likely corrupted or did not run to completion.\n\n" + "Message: " + ex.Message, "Data Read Error");
            }

            if (sw != null)
            {
                sw.WriteLine("\r\n===========================\r\nEnd of Report.");
                sw.Close();
            }
        }

        private void updateMainParams(bool writeNewDocument)
        {
            string scenNumStr = alternativeSelectBox.Text.Substring(1, alternativeSelectBox.Text.IndexOf("_") - 1);
            int scenNum = int.Parse(scenNumStr);

            string dbfPath = "C:\\magfire\\" + ConfigSettings.ReadSetting("analysisArea");
            string resultsPath = inputPath + "\\" + alternativeSelectBox.Text + "\\results";

            string[] stuff = ru.Meta_getMainInfo(dbfPath, resultsPath, scenNum);

            labAlternativeName.Text = stuff[0];
            labAnalysisArea.Text = ConfigSettings.ReadSetting("analysisArea");
            labSolverOption.Text = stuff[1];
            labClusterSize.Text = stuff[2];
            labNumberPeriods.Text = ConfigSettings.ReadSetting("PeriodCount");
            labExpLossNA.Text = stuff[3];
            labExpLossTR.Text = stuff[4];
            labBestSol.Text = stuff[5];

            if (writeNewDocument == true)
            {
                sw.WriteLine("Alternative Name: " + stuff[0]);
                sw.WriteLine("Analysis Area: " + ConfigSettings.ReadSetting("analysisArea"));
                sw.WriteLine("Solver Option: " + stuff[1]);
                sw.WriteLine("Cluster Size: " + stuff[2]);
                sw.WriteLine("Number of Periods: " + ConfigSettings.ReadSetting("PeriodCount"));
                sw.WriteLine();
                sw.WriteLine("Expected Loss, No Action: " + stuff[3]);
                sw.WriteLine("Expected Loss, Best Treatment: " + stuff[4]);
                sw.WriteLine("Best Solution Iteration: " + stuff[5]);
                sw.WriteLine();
            }
        }

        private void updateFireParams(bool writeNewDocument)
        {
            string scenNumStr = alternativeSelectBox.Text.Substring(1, alternativeSelectBox.Text.IndexOf("_") - 1);
            int scenNum = int.Parse(scenNumStr);

            string dbfPath = "C:\\magfire\\" + ConfigSettings.ReadSetting("analysisArea");

            Dictionary<int, string[]> fireStuff = ru.Meta_getFireScenInfo(dbfPath, scenNum);
            string allTheThings = "";

            if (fireStuff != null)
            {
                foreach (int i in fireStuff.Keys)
                {
                    string[] currElems = fireStuff[i];
                    allTheThings += "Fire Scenario: " + i.ToString() + "\r\n";
                    allTheThings += "   " + "Weight: " + currElems[0] + "\r\n";
                    allTheThings += "   " + "Description: " + currElems[1] + "\r\n";
                    allTheThings += "   " + "Ignition File: " + currElems[2] + "\r\n";
                    allTheThings += "   " + "FMS File: " + currElems[3] + "\r\n";
                    allTheThings += "   " + "Wind Speed: " + currElems[4] + "\r\n";
                    allTheThings += "   " + "Wind Direction: " + currElems[5] + "\r\n";
                    allTheThings += "   " + "Foliar Moist.: " + currElems[6] + "\r\n";
                    allTheThings += "\r\n";
                }
            }

            this.fireParamsTextBox.Text = allTheThings;

            if (writeNewDocument == true)
            {
                sw.WriteLine("===========================");
                sw.WriteLine("Fire Parameters");
                sw.WriteLine();
                sw.WriteLine(allTheThings);
            }
        }

        private void updateAreaConstraints(bool writeNewDocument)
        {
            string altPath = inputPath + "\\" + alternativeSelectBox.Text;
            List<string> areaStuff = ru.Meta_getAreaConstraints(altPath);

            if (writeNewDocument == true)
            {
                sw.WriteLine("===========================");
                sw.WriteLine("Acre Constraints\r\n");
                sw.WriteLine("NAME \tLOWER \tUPPER \tPERIOD");
            }

            foreach (string s in areaStuff)
            {
                string[] spl = s.Split('\t');
                dataGridView1.Rows.Add(spl);

                if (writeNewDocument == true)
                {
                    sw.WriteLine(s);
                }
            }
        }

        private void updateCostConstraints(bool writeNewDocument)
        {
            string altPath = inputPath + "\\" + alternativeSelectBox.Text;
            List<string> costStuff = ru.Meta_getCostConstraints(altPath);

            if (writeNewDocument == true)
            {
                sw.WriteLine("===========================");
                sw.WriteLine("Cost Constraints\r\n");
                sw.WriteLine("NAME \tLOWER \tUPPER \tPERIOD");
            }

            foreach (string s in costStuff)
            {
                string[] spl = s.Split('\t');
                dataGridView2.Rows.Add(spl);

                if (writeNewDocument == true)
                {
                    sw.WriteLine(s);
                }
            }
        }

        private void updateAcresTreated(bool writeNewDocument)
        {
            string gisPath = inputPath + "\\" + alternativeSelectBox.Text + "\\results\\gis";
            string treatPerFile = gisPath + "\\treatPeriod.tif";
            string treatRegFile = gisPath + "\\treatRegime.tif";

            if (!File.Exists(treatPerFile) || !File.Exists(treatRegFile))
            {
                MessageBox.Show("Treatment Schedule rasters not detected. Please create them using the\n\"Add OptFuels Data\" utility", "Files Not Found");
                return;
            }



        }

        private void printButton_Click(object sender, EventArgs e)
        {
            if (reportTextName.Equals(""))
            {
                MessageBox.Show("Could not determine report text file location. Please create a new one by checking the\n\"Write New Metadata Report\" box and pressing the \"Generate\" button.", "Report Print Error");
                return;
            }

            printScenDataDialog.Document = this.printScenDataDocument;
            DialogResult resOK = printScenDataDialog.ShowDialog();
            sr = new StreamReader(reportTextName);

            if (resOK == DialogResult.OK)
            {
                printScenDataDocument.Print();
            }
            
            sr.Close();
        }

        private void document_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            Font headFont = new Font("Calibri", 18, FontStyle.Bold);
            Font mainFont = new Font("Calibri", 12, FontStyle.Regular);
            
            float linesPerPage = 0;
            float yPos = 0;
            int count = 0;
            float leftMargin = e.MarginBounds.Left / 2;
            float topMargin = e.MarginBounds.Top / 2;
            string line = null;

            // Calculate the number of lines per page.
            linesPerPage = e.MarginBounds.Height / mainFont.GetHeight(e.Graphics);

            // Print each line of the file. 
            while (count < linesPerPage && (line = sr.ReadLine()) != null)
            {
                //line = sr.ReadLine();
                line = line.Replace("\t", "   ");
                yPos = topMargin + (count * mainFont.GetHeight(e.Graphics));
                e.Graphics.DrawString(line, mainFont, Brushes.Black, leftMargin, yPos, new StringFormat());
                count++;
            }

            // If more lines exist, print another page. 
            if (line != null)
                e.HasMorePages = true;
            else
                e.HasMorePages = false;
        }

        private void alternativeSelectBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            dataGridView2.Rows.Clear();
            dataGridView3.Rows.Clear();
        }

        private void clearOldReports(string resultsPath)
        {
            string[] listOfOldReports = Directory.GetFiles(resultsPath, "Report*");

            foreach (string s in listOfOldReports)
            {
                File.Delete(s);
            }
        }
    }
}
